import { computed, nextTick, ref, shallowRef } from 'vue';
import type { RouteRecordRaw } from 'vue-router';
import { defineStore } from 'pinia';
import { useBoolean } from '@sa/hooks';
import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
import { SetupStoreId } from '@/enum';
import { router } from '@/router';
import { createStaticRoutes, getAuthVueRoutes } from '@/router/routes';
import { ROOT_ROUTE } from '@/router/routes/builtin';
import { getRouteName, getRoutePath } from '@/router/elegant/transform';
import { fetchGetConstantRoutes, fetchGetUserRoutes, fetchIsRouteExist } from '@/service/api';
import { useAuthStore } from '../auth';
import { useTabStore } from '../tab';
import {
  filterAuthRoutesByRoles,
  getBreadcrumbsByRoute,
  getCacheRouteNames,
  getGlobalMenusByAuthRoutes,
  getSelectedMenuKeyPathByKey,
  isRouteExistByRouteName,
  sortRoutesByOrder,
  transformMenuToSearchMenus,
  updateLocaleOfGlobalMenus
} from './shared';

export const useRouteStore = defineStore(SetupStoreId.Route, () => {
  const authStore = useAuthStore();
  const tabStore = useTabStore();
  const { bool: isInitConstantRoute, setBool: setIsInitConstantRoute } = useBoolean();
  const { bool: isInitAuthRoute, setBool: setIsInitAuthRoute } = useBoolean();

  /**
   * Auth route mode
   *
   * It recommends to use static mode in the development environment, and use dynamic mode in the production
   * environment, if use static mode in development environment, the auth routes will be auto generated by plugin
   * "@elegant-router/vue"
   */
  const authRouteMode = ref(import.meta.env.VITE_AUTH_ROUTE_MODE);

  /** Home route key */
  const routeHome = ref(import.meta.env.VITE_ROUTE_HOME);

  /**
   * Set route home
   *
   * @param routeKey Route key
   */
  function setRouteHome(routeKey: LastLevelRouteKey) {
    routeHome.value = routeKey;
  }

  /** constant routes */
  const constantRoutes = shallowRef<ElegantConstRoute[]>([]);

  function addConstantRoutes(routes: ElegantConstRoute[]) {
    const constantRoutesMap = new Map<string, ElegantConstRoute>([]);

    routes.forEach(route => {
      constantRoutesMap.set(route.name, route);
    });

    constantRoutes.value = Array.from(constantRoutesMap.values());
  }

  /** auth routes */
  const authRoutes = shallowRef<ElegantConstRoute[]>([]);

  function addAuthRoutes(routes: ElegantConstRoute[]) {
    const authRoutesMap = new Map<string, ElegantConstRoute>([]);

    routes.forEach(route => {
      authRoutesMap.set(route.name, route);
    });

    authRoutes.value = Array.from(authRoutesMap.values());
  }

  const removeRouteFns: (() => void)[] = [];

  /** Global menus */
  const menus = ref<App.Global.Menu[]>([]);
  const searchMenus = computed(() => transformMenuToSearchMenus(menus.value));

  /** Get global menus */
  function getGlobalMenus(routes: ElegantConstRoute[]) {
    menus.value = getGlobalMenusByAuthRoutes(routes);
  }

  /** Update global menus by locale */
  function updateGlobalMenusByLocale() {
    menus.value = updateLocaleOfGlobalMenus(menus.value);
  }

  /** Cache routes */
  const cacheRoutes = ref<RouteKey[]>([]);

  /**
   * Exclude cache routes
   *
   * for reset route cache
   */
  const excludeCacheRoutes = ref<RouteKey[]>([]);

  /**
   * Get cache routes
   *
   * @param routes Vue routes
   */
  function getCacheRoutes(routes: RouteRecordRaw[]) {
    cacheRoutes.value = getCacheRouteNames(routes);
  }

  /**
   * Reset route cache
   *
   * @default router.currentRoute.value.name current route name
   * @param routeKey
   */
  async function resetRouteCache(routeKey?: RouteKey) {
    const routeName = routeKey || (router.currentRoute.value.name as RouteKey);

    excludeCacheRoutes.value.push(routeName);

    await nextTick();

    excludeCacheRoutes.value = [];
  }

  /** Global breadcrumbs */
  const breadcrumbs = computed(() => getBreadcrumbsByRoute(router.currentRoute.value, menus.value));

  /** Reset store */
  async function resetStore() {
    const routeStore = useRouteStore();

    console.log('🔄 开始重置路由store...');
    
    routeStore.$reset();
    resetVueRoutes();

    console.log('✅ 路由store重置完成，常量路由将在需要时重新初始化');
    
    // 不在这里立即初始化常量路由，让路由守卫来处理
    // 避免与认证流程产生冲突
  }

  /** Reset vue routes */
  function resetVueRoutes() {
    removeRouteFns.forEach(fn => fn());
    removeRouteFns.length = 0;
  }

  /** Init constant route */
  async function initConstantRoute() {
    if (isInitConstantRoute.value) return;

    console.log('=== 初始化常量路由开始 ===');
    console.log('当前路由模式:', authRouteMode.value);

    const staticRoute = createStaticRoutes();
    console.log('静态路由:', staticRoute);

    if (authRouteMode.value === 'static') {
      console.log('使用静态模式的常量路由');
      addConstantRoutes(staticRoute.constantRoutes);
    } else {
      console.log('使用动态模式，尝试获取常量路由');
      try {
        const { data, error } = await fetchGetConstantRoutes();
        console.log('获取常量路由结果:', { data, error });

        if (!error && data && data.length > 0) {
          console.log('使用服务端返回的常量路由');
          addConstantRoutes(data);
        } else {
          console.log('服务端常量路由为空或失败，使用静态常量路由');
          addConstantRoutes(staticRoute.constantRoutes);
        }
      } catch (err) {
        console.error('获取常量路由失败，使用静态常量路由:', err);
        addConstantRoutes(staticRoute.constantRoutes);
      }
    }

    console.log('常量路由数量:', constantRoutes.value.length);
    console.log('常量路由详情:', constantRoutes.value);

    setIsInitConstantRoute(true);
    console.log('=== 初始化常量路由结束 ===');
  }

  /** Init auth route */
  async function initAuthRoute() {
    console.log('=== initAuthRoute 开始 ===');
    console.log('当前路由模式:', authRouteMode.value);
    console.log('用户信息userId:', authStore.userInfo.userId);
    console.log('常量路由是否已初始化:', isInitConstantRoute.value);
    
    // 确保常量路由已经初始化
    if (!isInitConstantRoute.value) {
      console.log('常量路由未初始化，先初始化常量路由');
      await initConstantRoute();
    }
    
    // check if user info is initialized
    if (!authStore.userInfo.userId) {
      console.log('用户信息未初始化，开始初始化用户信息');
      await authStore.initUserInfo();
      console.log('用户信息初始化完成，userId:', authStore.userInfo.userId);
    }

    if (authRouteMode.value === 'static') {
      console.log('使用静态路由模式');
      initStaticAuthRoute();
    } else {
      console.log('使用动态路由模式');
      await initDynamicAuthRoute();
    }

    console.log('初始化首页标签');
    tabStore.initHomeTab();
    console.log('=== initAuthRoute 结束 ===');
  }

  /** Init static auth route */
  function initStaticAuthRoute() {
    const { authRoutes: staticAuthRoutes } = createStaticRoutes();

    if (authStore.isStaticSuper) {
      addAuthRoutes(staticAuthRoutes);
    } else {
      const filteredAuthRoutes = filterAuthRoutesByRoles(staticAuthRoutes, authStore.userInfo.roles);

      addAuthRoutes(filteredAuthRoutes);
    }

    handleConstantAndAuthRoutes();

    setIsInitAuthRoute(true);
  }

  /** Init dynamic auth route */
  async function initDynamicAuthRoute() {
    console.log('=== 动态路由初始化开始 ===');
    console.log('用户信息:', authStore.userInfo);
    
    // 强制调用专门的路由接口，不依赖用户信息中的路由数据
    console.log('🚀 调用专门的路由接口获取用户路由');
    
    try {
      console.log('📡 开始调用 fetchGetUserRoutes...');
      const { data, error } = await fetchGetUserRoutes();
      console.log('📡 fetchGetUserRoutes 调用结果:');
      console.log('- data:', data);
      console.log('- error:', error);

      if (!error && data) {
        console.log('✅ 获取到路由数据:', data);
        const { routes, home } = data;

        if (routes && routes.length > 0) {
          console.log('📋 路由数量:', routes.length);
          console.log('📋 路由详情:', JSON.stringify(routes, null, 2));

          // 转换后端路由格式为前端ElegantConstRoute格式
          console.log('🔄 开始转换路由格式...');
          const elegantRoutes = transformBackendRoutesToElegantRoutes(routes);
          console.log('🔄 转换后的路由:', elegantRoutes);

          console.log('➕ 添加认证路由...');
          addAuthRoutes(elegantRoutes);
          console.log('🔧 处理常量和认证路由...');
          handleConstantAndAuthRoutes();
          
          if (home) {
            console.log('🏠 设置首页路由:', home);
            setRouteHome(home);
          } else {
            console.log('🏠 使用默认首页路由: home');
            setRouteHome('home');
          }
          
          console.log('🔄 更新根路由重定向...');
          handleUpdateRootRouteRedirect('home');
          setIsInitAuthRoute(true);

          console.log('✅ 动态路由初始化成功');
          return;
        } else {
          console.warn('⚠️ 路由数据为空或无效');
        }
      } else {
        console.error('❌ 获取路由数据失败:', error);
      }
    } catch (err) {
      console.error('💥 调用路由接口异常:', err);
    }

    // 如果接口调用失败，尝试使用用户信息中的路由数据作为备选方案
    console.log('🔄 尝试使用用户信息中的路由数据作为备选方案');
    const userRoutes = authStore.userInfo.routes;
    
    if (userRoutes && userRoutes.length > 0) {
      console.log('📋 从用户信息中获取到路由，数量:', userRoutes.length);
      console.log('📋 用户信息路由详情:', JSON.stringify(userRoutes, null, 2));

      try {
        // 转换后端路由格式为前端ElegantConstRoute格式
        const elegantRoutes = transformBackendRoutesToElegantRoutes(userRoutes);
        console.log('🔄 转换后的用户信息路由:', elegantRoutes);

        addAuthRoutes(elegantRoutes);
        handleConstantAndAuthRoutes();
        setRouteHome('home');
        handleUpdateRootRouteRedirect('home');
        setIsInitAuthRoute(true);

        console.log('✅ 使用用户信息路由初始化成功');
      } catch (transformError) {
        console.error('💥 转换用户信息路由失败:', transformError);
      }
    } else {
      console.warn('⚠️ 用户信息中也没有路由数据');
      // 即使没有路由数据，也要设置初始化完成，避免无限循环
      setIsInitAuthRoute(true);
    }
    
    console.log('=== 动态路由初始化结束 ===');
  }

  /**
   * 转换后端路由数据为前端ElegantConstRoute格式
   * @param backendRoutes 后端返回的路由数据
   */
  function transformBackendRoutesToElegantRoutes(backendRoutes: any[]): ElegantConstRoute[] {
    console.log('🔄 开始转换后端路由数据，数量:', backendRoutes.length);
    console.log('🔄 原始路由数据:', JSON.stringify(backendRoutes, null, 2));
    
    const result = backendRoutes.map((route, index) => {
      console.log(`🔄 处理第 ${index + 1} 个路由:`, route.name || route.key);
      console.log(`🔄 路由详细信息:`, route);
      console.log(`🔄 组件信息:`, route.component, typeof route.component);
      
      // 确保路由名称和路径存在
      if (!route.name || !route.path) {
        console.warn('⚠️ 路由缺少必要字段:', route);
        return null;
      }
      
      // 确保组件字段是有效的字符串
      let component = route.component;
      let path = route.path;
      let originalUrl = undefined;
      
      // 处理外部链接 - 当 isFrame 为 true 且路径以 http 开头时
      if (route.isFrame === true && (path.startsWith('http://') || path.startsWith('https://'))) {
        console.log(`🔗 检测到外部链接:`, path);
        // 保存原始URL
        originalUrl = path;
        console.log(`🔗 保存原始URL:`, originalUrl);
        
        // 设置组件为 'iframe-page'
        if (!component || typeof component !== 'string') {
          component = 'iframe-page';
        }
        console.log(`🔗 使用组件:`, component);
      } else if (!component || typeof component !== 'string') {
        console.warn(`⚠️ 路由 ${route.name} 的组件字段无效:`, component, '使用默认组件');
        component = 'layout.base$view.' + route.name;
      }
      
      const elegantRoute: ElegantConstRoute = {
        name: route.name as any,
        path: path,
        component: component,
        meta: {
          title: route.meta?.title || route.label || route.name,
          i18nKey: route.meta?.i18nKey || `route.${route.name}`,
          icon: route.meta?.icon || 'mdi:menu',
          order: route.meta?.order !== undefined ? route.meta.order : (route.order || 0),
          roles: route.meta?.roles || [], // 使用后端返回的角色，如果为空则表示所有登录用户都可以访问
          hideInMenu: route.meta?.hideInMenu === true,
          keepAlive: route.meta?.keepAlive === true
        }
      };
      
      // 添加 isFrame 属性和原始URL
      if (route.isFrame === true) {
        console.log(`📑 设置isFrame=true, 原始URL=`, originalUrl || 'N/A');
        (elegantRoute as any).isFrame = true;
        
        if (originalUrl) {
          (elegantRoute as any).originalUrl = originalUrl;
        }
      }

      // 处理子路由
      if (route.children && Array.isArray(route.children) && route.children.length > 0) {
        console.log(`🔄 处理子路由，数量: ${route.children.length}`);
        const childRoutes = transformBackendRoutesToElegantRoutes(route.children);
        if (childRoutes.length > 0) {
          elegantRoute.children = childRoutes.filter(child => child !== null) as ElegantConstRoute[];
        }
      }

      console.log(`✅ 转换完成:`, elegantRoute.name, '组件:', elegantRoute.component);
      return elegantRoute;
    }).filter(route => route !== null) as ElegantConstRoute[];
    
    console.log('🔄 转换结果，有效路由数量:', result.length);
    console.log('🔄 最终转换结果:', JSON.stringify(result, null, 2));
    
    return result;
  }

  /** handle constant and auth routes */
  function handleConstantAndAuthRoutes() {
    console.log('=== 处理路由开始 ===');
    
    try {
      const allRoutes = [...constantRoutes.value, ...authRoutes.value];
      console.log('常量路由数量:', constantRoutes.value.length);
      console.log('认证路由数量:', authRoutes.value.length);
      console.log('所有路由:', allRoutes);

      const sortRoutes = sortRoutesByOrder(allRoutes);
      console.log('排序后的路由:', sortRoutes);

      console.log('🔄 开始转换为Vue路由...');
      console.log('🔄 转换前的路由数据:', JSON.stringify(sortRoutes, null, 2));
      const vueRoutes = getAuthVueRoutes(sortRoutes);
      console.log('✅ 转换后的Vue路由数量:', vueRoutes.length);
      console.log('✅ 转换后的Vue路由详情:', vueRoutes);

      console.log('🔄 重置Vue路由...');
      resetVueRoutes();

      console.log('🔄 添加路由到Vue Router...');
      addRoutesToVueRouter(vueRoutes);

      console.log('🔄 生成全局菜单...');
      getGlobalMenus(sortRoutes);
      console.log('✅ 生成的菜单:', menus.value);

      console.log('🔄 获取缓存路由...');
      getCacheRoutes(vueRoutes);
      
      console.log('✅ 路由处理完成！');
    } catch (error) {
      console.error('💥 处理路由时发生错误:', error);
      console.error('错误堆栈:', (error as Error).stack);
      
      // 即使出错也要设置初始化完成，避免无限循环
      setIsInitAuthRoute(true);
    }

    console.log('=== 处理路由结束 ===');
  }

  /**
   * Add routes to vue router
   *
   * @param routes Vue routes
   */
  function addRoutesToVueRouter(routes: RouteRecordRaw[]) {
    routes.forEach(route => {
      const removeFn = router.addRoute(route);
      addRemoveRouteFn(removeFn);
    });
  }

  /**
   * Add remove route fn
   *
   * @param fn
   */
  function addRemoveRouteFn(fn: () => void) {
    removeRouteFns.push(fn);
  }

  /**
   * Update root route redirect when auth route mode is dynamic
   *
   * @param redirectKey Redirect route key
   */
  function handleUpdateRootRouteRedirect(redirectKey: LastLevelRouteKey) {
    const redirect = getRoutePath(redirectKey);

    if (redirect) {
      const rootRoute: CustomRoute = { ...ROOT_ROUTE, redirect };

      router.removeRoute(rootRoute.name);

      const [rootVueRoute] = getAuthVueRoutes([rootRoute]);

      router.addRoute(rootVueRoute);
    }
  }

  /**
   * Get is auth route exist
   *
   * @param routePath Route path
   */
  async function getIsAuthRouteExist(routePath: RouteMap[RouteKey]) {
    const routeName = getRouteName(routePath);

    if (!routeName) {
      return false;
    }

    if (authRouteMode.value === 'static') {
      const { authRoutes: staticAuthRoutes } = createStaticRoutes();
      return isRouteExistByRouteName(routeName, staticAuthRoutes);
    }

    const { data } = await fetchIsRouteExist(routeName);

    return data;
  }

  /**
   * Get selected menu key path
   *
   * @param selectedKey Selected menu key
   */
  function getSelectedMenuKeyPath(selectedKey: string) {
    return getSelectedMenuKeyPathByKey(selectedKey, menus.value);
  }

  async function onRouteSwitchWhenLoggedIn() {
    await authStore.initUserInfo();
  }

  async function onRouteSwitchWhenNotLoggedIn() {
    // some global init logic if it does not need to be logged in
  }

  return {
    resetStore,
    routeHome,
    menus,
    searchMenus,
    updateGlobalMenusByLocale,
    cacheRoutes,
    excludeCacheRoutes,
    resetRouteCache,
    breadcrumbs,
    initConstantRoute,
    isInitConstantRoute,
    initAuthRoute,
    isInitAuthRoute,
    setIsInitAuthRoute,
    getIsAuthRouteExist,
    getSelectedMenuKeyPath,
    onRouteSwitchWhenLoggedIn,
    onRouteSwitchWhenNotLoggedIn
  };
});
